import random
import uuid
from suds import WebFault
from Autotests.Suites.StressTest.Operations.CommonOperations import CommonOperations
from Config.RunConfig import RunConfig, Options


class PartnerOperations:
    def __init__(self):
        self._operationsList = [
            self._addPartnerWithRandomLevel,
            self._addContactPerson,
            self._addContactNote,
            self._addCustomColumn,
            self._lookupTransport,
            self._getPartnerLevel,
            self._getRootPartnerName,
            self._getContactNoteInfo,
            self._getContactPersonInfoById,
            self._getPartnerPriceCurrency,
            self._getPartnersRuleAppliedTo,
            self._getAdvancedPartnerProperties,
            self._getAirBackupPartnerLicense,
            self._getPartnerInfo,
            self._getPartnerUrl,
            self._enumerateAllContactPersons,
            self._enumeratePartnerStateTransitions,
            self._enumeratePartnerFeatures,
            self._enumeratePartners,
            self._enumeratePartnerUrls,
            self._enumerateAllowedUpdatePackageVersions,
            self._enumerateTemplates,
            self._enumerateExternalPartnerProperties,
            self._enumerateAdvancedPartnerPropertiesByPartnerIds,
            self._enumerateCustomColumns,
            self._enumerateColumns,
            self._enumerateBillingContactPersons,
            self._enumerateAdvancedPartnerProperties,
            self._enumerateContactNotes,
            self._enumerateLastContactNotes,
            self._enumerateContactPersons,
            self._enumerateEndCustomerPrices,
            self._enumerateUniquePartnerStatesByPeriod,
        ]

        if  RunConfig().get(Options.StressTest.stressAllPartners) == 'True':
            self._operationsList.append(self._changePartnerState)
            self._operationsList.append(self._modifyContactNote)
            self._operationsList.append(self._modifyContactPerson)
            self._operationsList.append(self._modifyCustomColumn)
            self._operationsList.append(self._modifyPartner)
            self._operationsList.append(self._removeContactPerson)
            self._operationsList.append(self._removeCustomColumn)
            self._operationsList.append(self._removeNotificationRule)
            self._operationsList.append(self._removeNotificationTemplate)
            self._operationsList.append(self._removeNotificationTransport)
            self._operationsList.append(self._removePartner)
            self._operationsList.append(self._setPartnerUrl)
            self._operationsList.append(self._setPartnerPriceCurrency)
            self._operationsList.append(self._setPartnerBranding)
            self._operationsList.append(self._setEndCustomerPrice)
            self._operationsList.append(self._setAccountFeaturesById)


        self._parentPartnerName = 'IASO'
        self._partnersLevelCount = 4
        self._parentId = 1
        self._basePostAddress = {
            'country': 'BY',
            'state': 'state',
            'district': uuid.uuid4(),
            'city': uuid.uuid4(),
            'zipCode': uuid.uuid4(),
            'address': uuid.uuid4(),
        }
        self._baseCompanyInfo = {
            'postAddress': self._basePostAddress,
            'phoneNumber': uuid.uuid4(),
            'faxNumber': uuid.uuid4(),
            'websiteAddress': uuid.uuid4(),
            'legalCompanyName': 'IASOCompany',
            'chamberOfCommerceNumber': uuid.uuid4(),
            'vatNumber': uuid.uuid4(),
            'bankAccountNumber': uuid.uuid4(),
        }
        self._basePartnerInfo = {
            'parentId': int(self._parentId),
            'name': '',
            'level': '',
            'privilege': 'Regular',
            'childServiceTypes': 'AllInclusive',
            'serviceType': 'AllInclusive',
            'state': 'InTrial',
            'weight': 'Dynamic',
            'company': self._baseCompanyInfo,
            'advancedPartnerProperties': {
                'regionId': random.randint(1, 100),
                'responsibleUserId': 0,
            },
            'mailingOption': 'Undefined',
        }
        self._partnerLevelsPriority = {
            1: 'SubRoot',
            2: 'Distributor',
            3: 'SubDistributor',
            4: 'Reseller',
            5: 'EndCustomer'
        }
        self._partnerAction = [
            'Reject',
            'ApproveForTrial',
            'ApproveForProduction',
            'ApplyForProduction',
            'Deactivate',
            'Expire'
        ]
        self._planningStatus = [
            'Planned',
            'Done'
        ]
        self._contactType = [
            'Phone',
            'Email',
            'PersonalContact',
            'InstantMessenger'
        ]
        self._contactPersonType = [
            'AuthorizedSigner',
            'Administrative',
            'Technical',
            'Sales',
        ]
        self._partnerUrlType = [
            'Logo',
            'PresentationDownload',
            'DedicatedQuoteModel',
            'SharedQuoteModel',
        ]
        self._customerSize = [
            'Small',
            'Regular',
            'Medium',
            'Large',
        ]

    def _getRandomOperation(self):
        return random.choice(self._operationsList)

    def _addPartner(self, manserv, parentId, partnerLevel):
        self._basePartnerInfo['name'] = 'Partner_' + str(uuid.uuid4())
        self._basePartnerInfo['level'] = partnerLevel
        self._basePartnerInfo['parentId'] = int(parentId)
        self._basePartnerInfo['childServiceTypes'] = {
            'string': ['AllInclusive', 'SoftwareOnly'],
        }

        if partnerLevel == 'EndCustomer':
            self._basePartnerInfo['childServiceTypes'] = 'AllInclusive'

        parentLevel = manserv.GetPartnerInfoById(id = parentId).level
        print 'parent is ' + parentLevel
        partnerId = manserv.AddPartner(partnerInfo = self._basePartnerInfo)
        return partnerId

    def _addStressTestPartner(self, manserv):
        self._basePartnerInfo['name'] = 'StressTestPartner'
        self._basePartnerInfo['level'] = 'SubRoot'
        self._basePartnerInfo['parentId'] = 1
        self._basePartnerInfo['childServiceTypes'] = {
            'string': ['AllInclusive', 'SoftwareOnly'],
        }

        try:
            partnerId = manserv.AddPartner(partnerInfo = self._basePartnerInfo)
            return partnerId
        except Exception, e:
            print 'cant create stress test partner' + str(e)
            return None

    def _addPartnerWithRandomLevel(self, manserv, parentId):
        randomSubLevel = self._getRandomSubLevel(manserv, parentId)
        print 'random sublevel = ' + str(randomSubLevel)
        if randomSubLevel:
            self._addPartner(manserv, parentId, randomSubLevel)

    def _enumeratePartners(self, manserv, partnerId):
        manserv.EnumeratePartners(parentPartnerId = partnerId,
                                  fetchRecursively = True)

    def _getPartnerSubLevel(self, partnerLevel):
        for key, value in self._partnerLevelsPriority.items():
            if value == partnerLevel:
                return self._partnerLevelsPriority[key + 1]

    def _getRandomSubLevel(self, manserv, partnerId):
        level = manserv.GetPartnerInfoById(id = partnerId).level
        if level == 'EndCustomer':
            return None
        else:
            levelId = self._getPartnerLevelId(level)
            randomLevel = random.randint(levelId + 1, 5)
            return self._partnerLevelsPriority[randomLevel];

    def _getPartnerLevelId(self, partnerLevel):
        for key, value in self._partnerLevelsPriority.items():
            if value == partnerLevel:
                return key

    def _getPartnerLevel(self, manserv, partnerId):
        return manserv.GetPartnerInfoById(id = partnerId).level

    def _changePartnerState(self, manserv, partnerId):
         try:
            actionIndex = random.randint(0, len(self._partnerAction) - 1)
            action = self._partnerAction[actionIndex]
            manserv.ChangePartnerState(partnerId = partnerId, action = action, reason = uuid.uuid4())
         except WebFault:
            pass

    def _enumerateAllContactPersons(self, manserv, partnerId):
        personTypeIndex = random.randint(0, len(self._contactPersonType) - 1)
        personType = self._contactPersonType[personTypeIndex]
        manserv.EnumerateAllContactPersons(partnerId = partnerId,
            contactPersonType = personType, applyMaillingOption = 'true')

    def _enumeratePartnerStateTransitions(self, manserv, partnerId):
        manserv.EnumeratePartnerStateTransitions()

    def _enumeratePartnerFeatures(self, manserv, partnerId):
        manserv.EnumeratePartnerFeatures(partnerId = partnerId)

    def _enumeratePartnerUrls(self, manserv, partnerId):
        manserv.EnumeratePartnerUrls(partnerId = partnerId)

    def _getRootPartnerName(self, manserv, partnerId):
        manserv.GetRootPartnerName()

    def _enumerateAllowedUpdatePackageVersions(self, manserv, partnerId):
        manserv.EnumerateAllowedUpdatePackageVersions(partnerId = partnerId)

    def _addContactPerson(self, manserv, partnerId):
        manserv.AddContactPerson(partnerId = partnerId, title = uuid.uuid4(), firstName = uuid.uuid4(),
            lastName = uuid.uuid4(), position = uuid.uuid4(), emailAddress = uuid.uuid4(),
            phoneNumber = random.randint(1000, 1000000))

    def _addContactNote(self, manserv, partnerId):
        planningIndex = random.randint(0, len(self._planningStatus) - 1)
        planning = self._planningStatus[planningIndex]
        contactIndex = random.randint(0, len(self._contactType) - 1)
        contact = self._contactType[contactIndex]
        manserv.AddContactNote(partnerId = partnerId, contactPersonId = partnerId,
            dateTime = '2034-04-17T16:50:45', typeOfContact = contact, statusOfPlanning = planning,
            details = uuid.uuid4(), userId = random.randint(1, 1000))

    def _addCustomColumn(self, manserv, partnerId):
        manserv.AddCustomColumn(partnerId = partnerId, valueType = 'String', name = uuid.uuid4())

    def _getContactNoteInfo(self, manserv, partnerId):
        manserv.GetContactNoteInfo(contactNoteId = random.randint(1, 1000))

    def _getContactPersonInfoById(self, manserv, partnerId):
        manserv.GetContactPersonInfoById(contactPersonId = random.randint(1, 1000))

    def _getPartnerPriceCurrency(self, manserv, partnerId):
        manserv.GetPartnerPriceCurrency(partnerId = partnerId)

    def _getPartnersRuleAppliedTo(self, manserv, partnerId):
        manserv.GetPartnersRuleAppliedTo(ruleId = random.randint(1, 1000))

    def _getAdvancedPartnerProperties(self, manserv, partnerId):
        manserv.GetAdvancedPartnerProperties(partnerId = random.randint(1, 1000))

    def _getAirBackupPartnerLicense(self, manserv, partnerId):
        manserv.GetAirBackupPartnerLicense(partnerId = random.randint(1, 1000))

    def _getPartnerInfo(self, manserv, partnerId):
        manserv.GetPartnerInfo(name = manserv.GetRootPartnerName())

    def _getPartnerUrl(self, manserv, partnerId):
        manserv.GetPartnerUrl(partnerId = random.randint(1, 100), urlType = random.choice(self._partnerUrlType))

    def _lookupTransport(self, manserv, partnerId):
        #manserv.GetPartnersRuleAppliedTo(partnerId = partnerId, type = 'Smtp')
        pass

    def _enumerateTemplates(self, manserv, partnerId):
        manserv.EnumerateTemplates(partnerId = partnerId, partnerOnly = 'false')

    def _enumerateExternalPartnerProperties(self, manserv, partnerId):
        manserv.EnumerateExternalPartnerProperties(partnerId = partnerId)

    def _enumerateEndCustomerPrices(self, manserv, partnerId):
        manserv.EnumerateEndCustomerPrices(partnerId = partnerId)

    def _enumerateCustomColumns(self, manserv, partnerId):
        manserv.EnumerateCustomColumns(partnerId = partnerId)

    def _enumerateColumns(self, manserv, partnerId):
        manserv.EnumerateColumns(partnerId = partnerId)

    def _enumerateBillingContactPersons(self, manserv, partnerId):
        manserv.EnumerateBillingContactPersons(parentPartnerId = partnerId, depth = 'FullyRecursive')

    def _enumerateAdvancedPartnerProperties(self, manserv, partnerId):
        manserv.EnumerateAdvancedPartnerProperties(parentPartnerId = partnerId, fetchRecursively = 'true')

    def _enumerateAdvancedPartnerPropertiesByPartnerIds(self, manserv, partnerId):
        manserv.EnumerateAdvancedPartnerPropertiesByPartnerIds(partnerIds = partnerId)

    def _enumerateContactNotes(self, manserv, partnerId):
        manserv.EnumerateContactNotes(partnerId = partnerId)

    def _enumerateLastContactNotes(self, manserv, partnerId):
        manserv.EnumerateLastContactNotes(partners = partnerId)

    def _enumerateContactPersons(self, manserv, partnerId):
        manserv.EnumerateContactPersons(partnerId = partnerId)

    def _modifyContactNote(self, manserv, partnerId):
        noteId = random.randint(1, 100)
        manserv.ModifyContactNote(id = noteId, partnerId = partnerId, details = uuid.uuid4())

    def _modifyContactPerson(self, manserv, partnerId):
        personId = random.randint(1, 100)
        manserv.ModifyContactPerson(id = personId, partnerId = partnerId, title = uuid.uuid4())

    def _modifyCustomColumn(self, manserv, partnerId):
        columnId = random.randint(1, 100)
        manserv.ModifyCustomColumn(id = columnId, partnerId = partnerId, name = uuid.uuid4())

    def _modifyPartner(self, manserv, partnerId):
        manserv.ModifyPartner(id = random.randint(1, 1000), parentId = random.randint(1 , 1000),
                              name = 'Partner_modified_' + uuid.uuid4())

    def _enumerateUniquePartnerStatesByPeriod(self, manserv, partnerId):
        manserv.EnumerateUniquePartnerStatesByPeriod(startTime = '2013-04-17T16:50:45', endTime = '2034-04-17T16:50:45')

    def _removeContactPerson(self, manserv, partnerId):
        id = random.randint(1, 1000)
        if id % CommonOperations()._baseGrowthRate == 0:
            manserv.RemoveContactPerson(contactPersonId = random.randint(1, 1000))

    def _removeCustomColumn(self, manserv, partnerId):
        id = random.randint(1, 1000)
        if id % CommonOperations()._baseGrowthRate == 0:
            manserv.RemoveCustomColumn(customColumnId = random.randint(1, 1000))

    def _removeNotificationRule(self, manserv, partnerId):
        id = random.randint(1, 1000)
        if id % CommonOperations()._baseGrowthRate == 0:
            manserv.RemoveNotificationRule(id = random.randint(1, 1000))

    def _removeNotificationTemplate(self, manserv, partnerId):
        id = random.randint(1, 1000)
        if id % CommonOperations()._baseGrowthRate == 0:
            manserv.RemoveNotificationTemplate(id = random.randint(1, 1000))

    def _removeNotificationTransport(self, manserv, partnerId):
        id = random.randint(1, 1000)
        if id % CommonOperations()._baseGrowthRate == 0:
            manserv.RemoveNotificationTransport(id = random.randint(1, 1000))

    def _removePartner(self, manserv, partnerId):
        id = random.randint(1, 1000)
        if id % CommonOperations()._baseGrowthRate == 0:
            manserv.RemovePartner(partnerId = random.randint(1, 1000))

    def _setPartnerUrl(self, manserv, partnerId):
        urlTypeId = random.randint(0, len(self._partnerUrlType) - 1)
        manserv.SetPartnerUrl(partnerId = partnerId, urlType = self._partnerUrlType[urlTypeId], url = uuid.uuid4())

    def _setPartnerPriceCurrency(self, manserv, partnerId):
        manserv.SetPartnerPriceCurrency(partnerId = partnerId, currency = random.randint(1, 10))

    def _setPartnerBranding(self, manserv, partnerId):
         manserv.SetPartnerBranding(partnerId = partnerId, type = 'zip', content = uuid.uuid4())

    def _setEndCustomerPrice(self, manserv, partnerId):
         manserv.SetEndCustomerPrice(partnerId = partnerId, customerSize = random.choice(self._customerSize),
                                     lowThresholdInGb = random.randint(1, 100),
                                     highThresholdInGb = random.randint(1, 100),
                                     pricePerGb = random.randint(1, 100))

    def _setAccountFeaturesById(self, manserv, partnerId):
        manserv.SetAccountFeaturesById(accountId = random.randint(1, 1000),
                                       first = random.randint(1, 10),
                                       second = random.randint(1, 10))

